﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;


namespace Pixysoft.Framework.XSchEmA.Entity
{
    /// <summary>
    /// column schema
    /// </summary>
    public class ColumnSchema
    {
        private string tableName;
        private string columnName;
        private string comment;
        private string defaultValue; //null 代表没有默认值
        private bool isNullable = true;//还由pk决定！


        private DataTypeSchema dataType = new DataTypeSchema(null, -1, -1, -1);

        TableSchema table;

        /// <summary>
        /// tablename
        /// </summary>
        [XmlAttribute]
        public string TableName
        {
            get { return tableName; }
            set { tableName = value; }
        }
        /// <summary>
        /// column name
        /// </summary>
        [XmlAttribute]
        public string ColumnName
        {
            get { return columnName; }
            set { columnName = value; }
        }
        /// <summary>
        /// column comment
        /// </summary>
        [XmlAttribute]
        public string Comment
        {
            get { return comment; }
            set { comment = value; }
        }
        /// <summary>
        /// column default value
        /// </summary>
        [XmlAttribute]
        public string DefaultValue
        {
            get { return defaultValue; }
            set { defaultValue = value; }
        }
        /// <summary>
        /// column is nullable
        /// </summary>
        [XmlAttribute]
        public bool IsNullable
        {
            get { return isNullable; }
            set { isNullable = value; }
        }
        /// <summary>
        /// column datatype
        /// </summary>
        [XmlElement]
        public DataTypeSchema DataType
        {
            get { return dataType; }
            set { dataType = value; }
        }

        /// <summary>
        /// the table contains this column
        /// </summary>
        [XmlIgnore]
        public TableSchema Table
        {
            get { return table; }
            set { table = value; }
        }

        /// <summary>
        /// column schema
        /// </summary>
        public ColumnSchema() { }
        /// <summary>
        /// column schema
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="columnName"></param>
        /// <param name="datatype"></param>
        public ColumnSchema(string tableName, string columnName, DataTypeSchema datatype)
        {
            this.tableName = tableName;
            this.columnName = columnName;
            this.dataType = datatype;
        }
        /// <summary>
        /// column schema
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="columnName"></param>
        /// <param name="datatype"></param>
        /// <param name="isNullable"></param>
        public ColumnSchema(string tableName, string columnName, DataTypeSchema datatype, bool isNullable)
        {
            this.tableName = tableName;
            this.columnName = columnName;
            this.dataType = datatype;
            this.isNullable = isNullable;
        }
        /// <summary>
        /// column schema
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="columnName"></param>
        /// <param name="datatype"></param>
        /// <param name="isNullable"></param>
        /// <param name="defaultValue"></param>
        /// <param name="comment"></param>
        public ColumnSchema(string tableName, string columnName, DataTypeSchema datatype, bool isNullable, string defaultValue, string comment)
        {
            this.tableName = tableName;
            this.columnName = columnName;
            this.dataType = datatype;
            this.isNullable = isNullable;
            this.defaultValue = defaultValue;
            this.comment = comment;
        }

        /// <summary>
        /// to string
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return ColumnName;
        }
        /// <summary>
        /// check schema
        /// </summary>
        public void Inspection()
        {
            if (tableName == null)
                throw new Exception("001001");

            if (columnName == null)
                throw new Exception("001002");

            tableName = tableName.ToUpper().Trim();
            columnName = columnName.ToUpper().Trim();

            dataType.Inspection();
        }
        /// <summary>
        /// clone
        /// </summary>
        /// <returns></returns>
        public ColumnSchema Clone()
        {
            return new ColumnSchema(tableName, columnName, DataType.Clone(), IsNullable, defaultValue, comment);
        }
    }

    /// <summary>
    /// datatype schema
    /// </summary>
    public struct DataTypeSchema
    {
        private string dataType;
        private Int64 length;
        private int precision;
        private int scale;

        //09-09-22 不同数据库获取方式不同
        private bool isAutoIncrement;

        /// <summary>
        /// datatype name
        /// </summary>
        [XmlAttribute]
        public string DataType
        {
            get { return dataType; }
            set { dataType = value; }
        }
        /// <summary>
        /// varchar length
        /// </summary>
        [XmlAttribute]
        public Int64 Length
        {
            get { return length; }
            set { length = value; }
        }
        /// <summary>
        /// number precision
        /// </summary>
        [XmlAttribute]
        public int Precision
        {
            get { return precision; }
            set { precision = value; }
        }
        /// <summary>
        /// number scale
        /// </summary>
        [XmlAttribute]
        public int Scale
        {
            get { return scale; }
            set { scale = value; }
        }
        [XmlAttribute]
        public bool IsAutoIncrement
        {
            get { return isAutoIncrement; }
            set { isAutoIncrement = value; }
        }

        /// <summary>
        /// 字段类型
        /// </summary>
        /// <param name="dataType"></param>
        public DataTypeSchema(string dataType)
        {
            this.dataType = dataType;
            this.length = -1;
            this.precision = -1;
            this.scale = -1;
            this.isAutoIncrement = false;
        }
        /// <summary>
        /// datatype schema
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="length"></param>
        /// <param name="precision"></param>
        /// <param name="scale"></param>
        public DataTypeSchema(string dataType, Int64 length, int precision, int scale)
        {
            this.dataType = dataType;
            this.length = length;
            this.precision = precision;
            this.scale = scale;
            this.isAutoIncrement = false;
        }
        /// <summary>
        /// datatype schema
        /// </summary>
        /// <param name="dataType"></param>
        /// <param name="length"></param>
        /// <param name="precision"></param>
        /// <param name="scale"></param>
        public DataTypeSchema(string dataType, Int64 length, int precision, int scale, bool autoIncrement)
        {
            this.dataType = dataType;
            this.length = length;
            this.precision = precision;
            this.scale = scale;
            this.isAutoIncrement = autoIncrement;
        }

        /// <summary>
        /// check schema
        /// </summary>
        public void Inspection()
        {
            if (dataType == null)
                throw new Exception("001003");

            //dataType = dataType.ToUpper().Trim();
        }

        /// <summary>
        /// clone
        /// </summary>
        /// <returns></returns>
        public DataTypeSchema Clone()
        {
            DataTypeSchema schema = new DataTypeSchema(DataType, Length, Precision, Scale, IsAutoIncrement);

            return schema;
        }


        public override string ToString()
        {
            return DataType;
        }

    }
}
